home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / text / misc / nroff.lha / nroff / strings.c < prev    next >
C/C++ Source or Header  |  1997-01-24  |  6KB  |  324 lines

  1. /*
  2.  *    strings.c - String input/output processing for nroff word processor
  3.  *
  4.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  5.  *    net:    rosenkra@hall.cray.com
  6.  *    CIS:    71460,17
  7.  *    GENIE:    W.ROSENKRANZ
  8.  *
  9.  *    original author:
  10.  *
  11.  *    Stephen L. Browning
  12.  *    5723 North Parker Avenue
  13.  *    Indianapolis, Indiana 46220
  14.  *
  15.  *    history:
  16.  *
  17.  *    - Originally written in BDS C;
  18.  *    - Adapted for standard C by W. N. Paul
  19.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  20.  */
  21.  
  22. #undef NRO_MAIN                    /* extern globals */
  23.  
  24. #include <stdio.h>
  25. #include "nroff.h"
  26.  
  27.  
  28.  
  29. /*------------------------------*/
  30. /*    defstr            */
  31. /*------------------------------*/
  32. defstr (p)
  33. register char  *p;
  34. {
  35.  
  36. /*
  37.  *    Define a string. top level, read from command line.
  38.  *
  39.  *    we should read string without interpretation EXCEPT:
  40.  *
  41.  *    1) number registers are interpolated
  42.  *    2) strings indicated by \* are interpolated
  43.  *    3) arguments indicated by \$ are interpolated
  44.  *    4) concealed newlines indicated by \(newline) are eliminated
  45.  *    5) comments indicated by \" are eliminated
  46.  *    6) \t and \a are interpreted as ASCII h tab and SOH.
  47.  *    7) \\ is interpreted as backslash and \. is interpreted as a period.
  48.  *
  49.  *    currently, we do only 3. a good place to do it would be here before
  50.  *    putstr, after colstr...
  51.  */
  52.  
  53.     register char  *q;
  54.     register int    i;
  55.     char        name[MNLEN];
  56.     char        defn[MXMLEN];
  57.  
  58.  
  59.  
  60.     name[0] = '\0';
  61.     defn[0] = '\0';
  62.  
  63.  
  64.     /*
  65.      *   skip the .ds and get to the name...
  66.      */
  67.     q = skipwd (p);
  68.     q = skipbl (q);
  69.  
  70.     /*
  71.      *   ok, name now holds the name. make sure it is valid (i.e. first
  72.      *   char is alpha...). getwrd returns the length of the word.
  73.      */
  74.     i = getwrd (q, name);
  75.     if (!name[0])
  76.     {
  77.         fprintf (err_stream,
  78.             "***%s: missing or illegal string definition name\n",
  79.             myname);
  80.         err_exit (-1);
  81.     }
  82.  
  83.     /*
  84.      *   truncate to 2 char max name.
  85.      */
  86.     if (i > 2)
  87.         name[2] = EOS;
  88.  
  89.  
  90.     /*
  91.      *   skip the name to get to the string. it CAN start with a " to
  92.      *   have leading blanks...
  93.      */
  94.     q = skipwd (q);
  95.     q = skipbl (q);
  96.  
  97.  
  98.  
  99.     /*
  100.      *   read rest of line from input stream and collect string into
  101.      *   temp buffer defn
  102.      */
  103.     if ((i = colstr (q, defn)) == ERR)
  104.     {
  105.         fprintf (err_stream,
  106.             "***%s: string definition too long\n", myname);
  107.         err_exit (-1);
  108.     }
  109.  
  110.  
  111.     /*
  112.      *   store the string
  113.      */
  114.     if (putstr (name, defn) == ERR)
  115.     {
  116.         fprintf (err_stream,
  117.             "***%s: string definition table full\n", myname);
  118.         err_exit (-1);
  119.     }
  120. }
  121.  
  122.  
  123.  
  124.  
  125.  
  126. /*------------------------------*/
  127. /*    colstr            */
  128. /*------------------------------*/
  129. colstr (p, d)
  130. register char  *p;
  131. char           *d;
  132. {
  133.  
  134. /*
  135.  *    Collect string definition from input stream
  136.  */
  137.  
  138.     register int    i = 0;
  139.     char           *pstart = p;
  140.  
  141.  
  142.  
  143.     /*
  144.      *   if there is a " here, we have leading blanks (skipbl in caller
  145.      *   found it). just get past it...
  146.      */
  147.     if (*p == '\"')
  148.         p++;
  149.  
  150.  
  151.     while (*p != EOS)
  152.     {
  153.         /*
  154.          *   are we over the length limit for a single string?
  155.          */
  156.         if (i >= MXMLEN - 1)
  157.         {
  158.             d[i - 1] = EOS;
  159.             return (ERR);
  160.         }
  161.  
  162.         /*
  163.          *   "i break for comments..."
  164.          */
  165.         if (*p == '\\' && *(p+1) == '\"')
  166.         {
  167.             /*
  168.              *   first back over any whitespace between comment
  169.              *   start and last character in line. remember to
  170.              *   decrement counter i, too...
  171.              */
  172.             p--;
  173.             while (isspace (*p) && p > pstart && i > 0)
  174.             {
  175.                 p--;
  176.                 i--;
  177.             }
  178.  
  179.             /*
  180.              *   now skip over the comment until we reach the
  181.              *   trailing newline
  182.              */
  183.             while (*p != EOS)
  184.             {
  185.                 if (*p == '\n' || *p == '\r')
  186.                     break;
  187.                 p++;
  188.             }
  189.         }
  190.  
  191.         /*
  192.          *   stop at the newline...
  193.          */
  194.         if (*p == '\n' || *p == '\r')
  195.             break;
  196.  
  197.         /*
  198.          *   copy it
  199.          */
  200.         d[i++] = *p++;
  201.     }
  202.     d[i] = EOS;
  203.     return (i);
  204. }
  205.  
  206.  
  207.  
  208.  
  209.  
  210. /*------------------------------*/
  211. /*    putstr            */
  212. /*------------------------------*/
  213. putstr (name, p)
  214. register char  *name;
  215. register char  *p;
  216. {
  217.  
  218. /*
  219.  *    Put string definition into (macro) table
  220.  *
  221.  *    NOTE: any expansions of things like number registers SHOULD
  222.  *    have been done already. strings and macros share mb buffer
  223.  */
  224.  
  225.  
  226.     /*
  227.      *   any room left? (did we exceed max number of possible macros)
  228.      */
  229.     if (mac.lastp >= MXMDEF)
  230.         return (ERR);
  231.  
  232.     /*
  233.      *   will new one fit in big buffer?
  234.      */
  235.     if (mac.emb + strlen (name) + strlen (p) + 1 > &mac.mb[MACBUF])
  236.     {
  237.         return (ERR);
  238.     }
  239.  
  240.  
  241.     /*
  242.      *   add it...
  243.      *
  244.      *   bump counter, set ptr to name, copy name, copy def.
  245.      *   finally increment end of macro buffer ptr (emb).
  246.      *
  247.      *   string looks like this in mb:
  248.      *
  249.      *    mac.mb[MACBUF]        size of total buf
  250.      *    lastp < MXMDEF        number of macros/strings possible
  251.      *    *mnames[MXMDEF]        -> names, each max length
  252.      *    ...______________________________...____________________...
  253.      *        / / /|X|X|0|string definition      |0| / / / / / / /
  254.      *    .../_/_/_|_|_|_|_________________...___|_|/_/_/_/_/_/_/_...
  255.      *            ^
  256.      *            |
  257.      *            \----- mac.mnames[mac.lastp] points here
  258.      *
  259.      *   both the 2 char name (XX) and the descripton are null term and
  260.      *   follow one after the other.
  261.      */
  262.     ++mac.lastp;
  263.     mac.mnames[mac.lastp] = mac.emb;
  264.     strcpy (mac.emb, name);
  265.     strcpy (mac.emb + strlen (name) + 1, p);
  266.     mac.emb += strlen (name) + strlen (p) + 2;
  267.     return (OK);
  268. }
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275. /*------------------------------*/
  276. /*    getstr            */
  277. /*------------------------------*/
  278. char   *getstr (name)
  279. register char  *name;
  280. {
  281.  
  282. /*
  283.  *    Get (lookup) string definition from namespace
  284.  */
  285.  
  286.     register int    i;
  287.  
  288.     /*
  289.      *   loop for all macros, starting with last one
  290.      */
  291.     for (i = mac.lastp; i >= 0; --i)
  292.     {
  293.         /*
  294.          *   is this REALLY a macro?
  295.          */
  296.         if (mac.mnames[i])
  297.         {
  298.             /*
  299.              *   if it compares, return a ptr to it
  300.              */
  301.             if (!strcmp (name, mac.mnames[i]))
  302.             {
  303. /*!!!debug            puts (mac.mnames[i]);*/
  304.  
  305.                 if (mac.mnames[i][1] == EOS)
  306.                     return (mac.mnames[i] + 2);
  307.                 else
  308.                     return (mac.mnames[i] + 3);
  309.             }
  310.         }
  311.     }
  312.  
  313.     /*
  314.      *   none found, return null
  315.      */
  316.     return (NULL_CPTR);
  317. }
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.